package com.jlb.base.ctrl;

import com.jlb.core.SessionTools;
import com.jlb.core.entity.BeanRet;
import com.jlb.core.enums.SessionEnum;
import com.jlb.core.exceptions.BaseException;
import com.jlb.core.tools.JwtToken;
import com.jlb.core.tools.redis.RedisUtils;
import com.jlb.platform.entity.PlatformAccount;
import com.jlb.setting.entity.Setting;
import com.jlb.setting.service.SessionSV;
import com.jlb.setting.service.SettingSV;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 账户 控制器
 *
 * @author pi-top
 */
@RestController
@RequestMapping("/login")
@Slf4j
@Api(value = "账户控制器", description = "账户控制器")
public class TokenCtrl {

    @Resource
    protected RedisUtils redisUtils;

    @Resource
    private SessionSV sessionSV;

    @Resource
    private SettingSV settingSV;


    /**
     * 登录用户系统
     * 1.会话构建
     * 2.创建header信息
     *
     * @param account  账户
     * @param password 密码
     * @return BeanRet
     */
    @ApiOperation(value = "查询DomainLog一个详情信息", notes = "查询DomainLog一个详情信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "account", value = "账户", required = true, dataType = "java.lang.String", paramType = "query"),
            @ApiImplicitParam(name = "password", value = "密码", required = true, dataType = "java.lang.String", paramType = "query")
    })
    @GetMapping(value = "/user/signin")
    @ResponseBody
    public BeanRet userLogin(String account, String password, HttpServletResponse response) {

        //1.会话构建
        String token = sessionSV.buildUserSession(account, password);
        log.info(token);

        //2.创建header信息以及cookie信息
        response.addHeader(SessionEnum.Token.name(), token);

        return BeanRet.create(true, BaseException.BaseExceptionEnum.Success, (Object) token);
    }


    /**
     * 登录用户系统
     * 1.会话构建
     * 2.创建header信息
     *
     * @param account 账户
     * @return BeanRet
     */
    @ApiOperation(value = "登录用户系统", notes = "登录用户系统")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "account", value = "账户", required = true, dataType = "java.lang.String", paramType = "query")
    })
    @GetMapping(value = "/mgt/user/signin")
    @ResponseBody
    public BeanRet mgtLoginUserAccount(String account, HttpServletResponse response) {

        //1.会话构建
        String token = sessionSV.buildUserSession(account, PlatformAccount.PlatformAccountEnum.Platform.name());
        log.debug(token);

        //2.创建header信息以及cookie信息
        response.addHeader(SessionEnum.Token.name(), token);
        Setting setting = settingSV.loadByK(Setting.Key.MgtLoginUserAccountUrl.name());
        String url = setting.getV().replace("{token}", token);
        return BeanRet.create(true, BaseException.BaseExceptionEnum.Success, (Object) url);
    }


    /**
     * 登录后台系统
     * 1.会话构建
     * 2.创建header信息
     *
     * @param account  账户
     * @param password 密码
     * @return BeanRet
     */
    @ApiOperation(value = "查询DomainLog一个详情信息", notes = "查询DomainLog一个详情信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "account", value = "账户", required = true, dataType = "java.lang.String", paramType = "query"),
            @ApiImplicitParam(name = "password", value = "密码", required = true, dataType = "java.lang.String", paramType = "query")
    })
    @GetMapping(value = "/mgt/signin")
    @ResponseBody
    public BeanRet platformLogin(String account, String password, HttpServletResponse response) {

        //1.会话构建
        String token = sessionSV.buildPlatformSession(account, password);
        log.info(token);

        //2.创建header信息以及cookie信息
        response.addHeader(SessionEnum.Token.name(), token);

        return BeanRet.create(true, BaseException.BaseExceptionEnum.Success, (Object) token);
    }


    /**
     * 注销局部session
     * 1.获取token
     * 2.拿出token中注销的指令以及sessionkey准备注销
     * 3.拿出本地token进行注销
     * 4.返回注销成功
     *
     * @return BeanRet
     */
    @ApiOperation(value = "SSO回调方法", notes = "SSO回调方法")
    @PostMapping(value = "/invalidate")
    @ResponseBody
    public BeanRet invalidate(HttpServletRequest request) {
        //1.获取token
        String token = request.getHeader(SessionEnum.Authorization.name());
        if (StringUtils.isBlank(token)) {
            return BeanRet.create();
        }
        String sso_secret = settingSV.loadByK(Setting.Key.Token_Secret.name()).getV();
        boolean isVerifier = JwtToken.verifier(token, sso_secret);
        if (!isVerifier) {
            return BeanRet.create(false, BaseException.BaseExceptionEnum.Session_Error);
        }

        //2.拿出token中注销的指令以及sessionkey准备注销
        String account = JwtToken.getTokenValue(token, sso_secret, SessionEnum.Account.name());
        String sessionKey = SessionTools.Instance.genSessionKey(account);
        //3.拿出本地token进行注销
        redisUtils.del(sessionKey);

        //4.返回注销成功
        return BeanRet.create(true, BaseException.BaseExceptionEnum.Success);
    }
}
